﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace XNA_TD.Menue
{

    public class TowerMenuePart : IRunable, IUpdate, IDraw
    {
        public Texture2D texture;
        public Type type;
        public Tower tower;
        VertexPositionColor[] vertices;
        static BasicEffect basicEffect = null;

        public TowerMenuePart(Type type)
            : base(Priority.GUI)
        {
            this.type = type;
            tower = (Tower)Activator.CreateInstance(type, Vector3.Zero);

            var renderTarget = new RenderTarget2D(graphics.GraphicsDevice, 80, 80, false, graphics.GraphicsDevice.DisplayMode.Format, DepthFormat.Depth24);

            var guiViewMatrix = Matrix.CreateLookAt(new Vector3(1, 1, 1), tower.position, Vector3.Up);
            float aspect = graphics.GraphicsDevice.DisplayMode.AspectRatio;
            var guiProjectionMatrix = Matrix.CreatePerspectiveFieldOfView(
                MathHelper.ToRadians(60),
                aspect,
                .1f,
                5f);

            shader.Parameters["ViewProjection"].SetValue(guiViewMatrix * guiProjectionMatrix);

            graphics.GraphicsDevice.SetRenderTarget(renderTarget);
            graphics.GraphicsDevice.Clear(Color.Transparent);
            tower.Draw();
            texture = (Texture2D)renderTarget;

            kamera.UpdateShader();

            if (basicEffect == null)
            {
                basicEffect = new BasicEffect(graphics.GraphicsDevice);
                basicEffect.DiffuseColor = Color.Red.ToVector3();
                basicEffect.VertexColorEnabled = true;
            }
        }

        public void Update()
        {
            if (buttonPressed.MouseRightButtonPressed())
            {
                UnRegister(this);
                new BauMenue();
                return;
            }
            else if (buttonPressed.MouseLeftButtonPressed())
            {
                if(map.istBebaubar(new Vector2(tower.position.X,tower.position.Z)))
                {
                    Register((Tower)Activator.CreateInstance(type, tower.position));
                    new BauMenue();
                    UnRegister(this);
                    return;
                }
            }
            Ray ray = GUI.GetMouseRay();
            var dist = ray.Intersects(new Plane(Vector3.Up, -tower.position.Y));
            if (dist.HasValue)
            {
                tower.position = ray.Position + dist.Value * ray.Direction;
                tower.position.X = (int)(tower.position.X + .5f);
                tower.position.Z = (int)(tower.position.Z + .5f);
                if (tower.position.X > 0 && tower.position.Z > 0 && tower.position.X < terrain.terrainWidth && tower.position.Z < terrain.terrainHeight)
                {
                    tower.position.Y = terrain.getHeight(tower.position.X, tower.position.Z);
                }
            }
        }

        public override void Load()
        {
            List<VertexPositionColor> verticesList = new List<VertexPositionColor>();
            Color color = Color.Red;

            var copy = new Dictionary<Vector2, bool>(map.bebaubar);

            foreach (var node in map.bebaubar)
            {
                if (node.Value)
                {
                    float height = terrain.getHeight(node.Key.X, node.Key.Y);
                    var p1 = new VertexPositionColor(new Vector3(node.Key.X,height,node.Key.Y), color);
                    var p2 = new VertexPositionColor(new Vector3(node.Key.X + 1,height,node.Key.Y), color);
                    var p3 = new VertexPositionColor(new Vector3(node.Key.X,height,node.Key.Y + 1), color);
                    var p4 = new VertexPositionColor(new Vector3(node.Key.X + 1, height, node.Key.Y + 1), color);
                    verticesList.Add(p1);
                    verticesList.Add(p2);
                    verticesList.Add(p1);
                    verticesList.Add(p3);

                    if (!map.istBebaubarOhneTestDesPfades(new Vector2(node.Key.X, node.Key.Y + 1)))
                    {
                        verticesList.Add(p4);
                        verticesList.Add(p3);
                    }

                    if (!map.istBebaubarOhneTestDesPfades(new Vector2(node.Key.X + 1, node.Key.Y)))
                    {
                        verticesList.Add(p4);
                        verticesList.Add(p2);
                    }
                }
            }
            
            vertices = verticesList.ToArray();
        }

        public override void UnLoad()
        {
        }

        public void Draw()
        {
            if (map.istBebaubarOhneTestDesPfades(new Vector2(tower.position.X, tower.position.Z)))
            {
                tower.Draw();
            }
            basicEffect.View = viewMatrix;
            basicEffect.Projection = projectionMatrix;
            basicEffect.World = Matrix.CreateTranslation(-.5f, .01f, -.5f);
            foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
            {
                pass.Apply();
                graphics.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.LineList, vertices, 0, vertices.Length / 2, VertexPositionColor.VertexDeclaration);
            }
        }
    }

    class BauMenue : GUI
    {
        private Texture2D top, mid, bot = null;
        private Rectangle rTop, rMid, rBot;

        private static List<TowerMenuePart> tower;

        public BauMenue()
        {
        }

        public static void Initialize()
        {
            tower = new List<TowerMenuePart>();
            tower.Add(new TowerMenuePart(typeof(Block)));
            tower.Add(new TowerMenuePart(typeof(MGTower)));
            tower.Add(new TowerMenuePart(typeof(ATTower)));
            tower.Add(new TowerMenuePart(typeof(AARTower)));
        }

        public override void Draw()
        {
            var depthStencilState = graphics.GraphicsDevice.DepthStencilState;
            spriteBatch.Begin();
            spriteBatch.Draw(top, rTop, Color.White);
            spriteBatch.Draw(mid, rMid, Color.White);
            spriteBatch.Draw(bot, rBot, Color.White);

            Vector2 pos = new Vector2(rTop.X + 10, rTop.Y + 10);

            foreach (var pic in tower)
            {
                spriteBatch.Draw(pic.texture, pos, Color.White);
                pos.Y += 70;
                spriteBatch.DrawString(DebugInfo.Instance.debugFont, "Schaden: " + pic.tower.lvlInfo.attackDmg, pos, Color.Black);
                pos.Y += 15;
                spriteBatch.DrawString(DebugInfo.Instance.debugFont, "Reichweite: " + pic.tower.lvlInfo.attackRange, pos, Color.Black);
                pos.Y += 15;
                spriteBatch.DrawString(DebugInfo.Instance.debugFont, "Feuerrate: " + pic.tower.lvlInfo.fireRate, pos, Color.Black);
                pos.Y += 15;
                spriteBatch.DrawString(DebugInfo.Instance.debugFont, "Preis: " + pic.tower.lvlInfo.preis, pos, Color.Black);
                pos.Y += 20;
            }

            spriteBatch.End();
            graphics.GraphicsDevice.DepthStencilState = depthStencilState;
        }

        public override void Update()
        {
            base.Update();
            if (mouseInside == false)
            {
                if (buttonPressed.MouseLeftButtonPressed())
                {
                    SelectTowerToUpgrade();
                }
            }
        }

        public override void Load()
        {
            if (bot == null)
            {
                top = Content.Load<Texture2D>("Menue/baumenue_top");
                mid = Content.Load<Texture2D>("Menue/baumenue_mid");
                bot = Content.Load<Texture2D>("Menue/baumenue_bot");

                rTop = new Rectangle(
                    0,
                    30,
                    100,
                    20);
                rMid = new Rectangle(
                    0,
                    50,
                    100,
                    0);
                rBot = new Rectangle(
                    0,
                    0,
                    100,
                    20);
                size.Y = 30;
                size.Width = 100;
                Resize();
            }
        }

        public override void Resize()
        {
            rTop.X = graphics.GraphicsDevice.Viewport.Width - 100;
            rMid.X = graphics.GraphicsDevice.Viewport.Width - 100;
            rMid.Height = graphics.GraphicsDevice.Viewport.Height - 40;
            rBot.X = graphics.GraphicsDevice.Viewport.Width - 100;
            rBot.Y = graphics.GraphicsDevice.Viewport.Height - 20;

            size.X = graphics.GraphicsDevice.Viewport.Width - 100;
            size.Height = rBot.Y - rTop.Y;
        }

        public override void MouseClick()
        {

            Vector2 pos = new Vector2(rTop.X + 10, rTop.Y + 10);

            foreach (var pic in tower)
            {
                if (GUI.MouseInside(new Rectangle((int)pos.X, (int)pos.Y, 80, 80)) && pic.tower.lvlInfo.preis <= geld)
                {
                    Register(pic);
                    UnRegister(this);
                    return;
                }
                pos.Y += 70 + 15 + 15 + 15 + 20;
            }
        }
    }
}
